/*
 * Copyright 2003-2005 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */


#ifndef INLINE
#include "../Types.h"
#include "typestack.h"
#define INLINE
#endif

INLINE void type_list_init( type_list * list )
{
	list->head = NULL;
	list->tail = NULL;
	list->count = 0;
}

INLINE void type_list_add_head( type_list * list, type_item * item )
{
	item->next = list->head;
	list->head = item;
	if ( list->tail == NULL ) list->tail = item;
	list->count++;
}

INLINE void type_list_add_tail( type_list * list, type_item * item )
{
	if ( list->tail == NULL )
	{
		list->tail = item;
		list->head = item;
		list->count++;
		return;
	}
	item->next = NULL;
	list->tail->next = item;
	list->tail = item;
	list->count++;
}

INLINE type_item * type_list_remove_head( type_list * list )
{
	if ( list->count > 0)
	{
		type_item * item = list->head;
		list->head = item->next;
		list->count--;
		if (list->count > 0)
		{
			list->tail = NULL;
		}
		
		item->next = NULL;
		return item;
	}
	return NULL;
}

/* type_list_remove_tail not available. 
 * would require a double linked list. 
 */

INLINE void type_list_clear( type_list * list )
{
	while ( list->count > 0 )
	{
		type_item_free( type_list_remove_head( list ) );
	}
}


INLINE void type_stack_init( type_stack * stack )
{
	stack->count = 0;
	stack->top = NULL;
}


INLINE void type_stack_push( type_stack * stack )
{
	type_item * item = type_item_alloc();
	item->next = stack->top;
	stack->top = item;
	stack->count++;
}

INLINE type_item * type_stack_remove( type_stack * stack )
{
	type_item * item;
	
	if ((stack)->count == 0)
		return NULL;

	item = stack->top;
	stack->top = item->next;
	stack->count--;
	
	item->next = NULL;
	return item;
}

INLINE void type_stack_pop( type_stack * stack )
{
	type_item_free( type_stack_remove( stack ));
}

INLINE void type_stack_clear( type_stack * stack )
{
	while ( stack->count > 0 )
		type_stack_pop( stack );
}
